package cn.virens.database.serviceimpl.sys;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.virens.common.MapUtil;
import cn.virens.database.common.BaseServiceImpl;
import cn.virens.database.mysql.mapper.sys.SysRoleMapper;
import cn.virens.database.mysql.model.sys.SysRole;
import cn.virens.database.service.sys.SysRoleService;
import cn.virens.util.Assert;
import cn.virens.web.components.beetl.tag.menus.Menu;
import cn.virens.web.components.beetl.tag.menus.MenuProvider;
import cn.virens.web.components.spring.permission.PermissionNode;
import cn.virens.web.components.spring.permission.PermissionNodeList;
import cn.virens.web.components.spring.permission.PermissionParam;

/**
 * 角色管理 - sys_role
 *
 * @author Virens
 * @since  2018-08-25 15:39:59
 */
@Service
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole> implements MenuProvider, SysRoleService {
	private static final String MENU_CACHE = "menus-cache";

	public SysRoleServiceImpl() {
		super(SysRole.class);
	}

	@Override
	@Transactional(readOnly = true)
	@Cacheable(cacheNames = MENU_CACHE, key = "#p0", unless = "#result == null")
	public List<Menu> getMenus(String account) {
		Assert.isEmpty(account, "账号不可为空");

		List<Map<String, Object>> maps = mBaseMapper.getResources(account);
		if (maps == null || maps.isEmpty()) { return null; }

		List<Menu> answer = new ArrayList<>();
		for (Map<String, Object> map0 : maps) {
			Integer id0 = MapUtil.getIntValue(map0, "id");
			Integer pid0 = MapUtil.getIntValue(map0, "pid");
			if (pid0 != null && pid0 > 0) {
				continue;
			}

			Menu root = Menu.parent(null);
			root.setIcon(MapUtil.getString(map0, "icon"));
			root.setName(MapUtil.getString(map0, "name"));
			root.setLinkurl(MapUtil.getString(map0, "linkurl"));
			root.setIdentity(MapUtil.getString(map0, "identity"));

			// 查找下级菜单
			if (id0 == null || id0 == 0) {
				continue;
			}
			for (Map<String, Object> map1 : maps) {
				Integer pid1 = MapUtil.getIntValue(map1, "pid");
				if (pid1 == null || pid1 != id0) {
					continue;
				}

				Menu children = Menu.parent(root);
				children.setIcon(MapUtil.getString(map1, "icon"));
				children.setName(MapUtil.getString(map1, "name"));
				children.setLinkurl(MapUtil.getString(map1, "linkurl"));
				children.setIdentity(MapUtil.getString(map1, "identity"));

				root.addChildrens(children);
			}

			// 将当前菜单节点添加到返回数组
			answer.add(root);
		}

		return answer;
	}

	@Override
	@Transactional(readOnly = true)
	public List<PermissionNode> getPermission(Integer roleId) {
		PermissionNodeList answer = new PermissionNodeList();
		for (Map<String, Object> map : mBaseMapper.selectResources(roleId)) {
			PermissionNode node = new PermissionNode();
			node.setPerms(MapUtil.getString(map, "permission"));
			node.setName(MapUtil.getString(map, "name", null));
			node.setPid(MapUtil.getString(map, "pid", null));
			node.setId(MapUtil.getString(map, "id", null));

			answer.add(node);
		}

		return answer;
	}

	@Override
	@Transactional(readOnly = false)
	@CacheEvict(cacheNames = MENU_CACHE, allEntries = true)
	public int putPermission(Integer role, List<PermissionParam> resources) {
		mBaseMapper.deleteResources(role);

		int answer = 0;
		for (PermissionParam record : resources) {
			if (record.getView() || record.getManage()) {
				answer += mBaseMapper.insertResources(record);
			}
		}

		return answer;
	}

}
